#include <linux/init.h>
#include <linux/module.h>
#include <linux/io.h>

MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("Bruce.zc_wang");


static volatile unsigned long phy_base_addr;
static volatile unsigned long vir_base_addr;
static volatile unsigned long *GPL2CON;
static volatile unsigned long *GPL2DAT;
static volatile unsigned long *GPL2PUD;

static void gpio_led_phy2vir(void)
{
	phy_base_addr = 0x11000100;
	vir_base_addr = (unsigned long)ioremap(phy_base_addr, 0x0c);
	GPL2CON = (unsigned long *)(vir_base_addr + 0x00);
	GPL2DAT = (unsigned long *)(vir_base_addr + 0x04);
	GPL2PUD = (unsigned long *)(vir_base_addr + 0x08);
}

static void gpio_led_cfg(void)
{
	//stay other ports configure not changed
	//0x1 is mean to if GPL2CON[0] is alreay configured to 1,stay it and only clear bit1, bit2, bit3
	*GPL2CON &= 0xFFFFFFF1;
	//configure to output
	*GPL2CON |= 0x00000001;
	//set pull up to output high level
	*GPL2PUD |= 0x0003;
}

static void gpio_led_on(void)
{
	*GPL2DAT |= 0x01;
}

static void gpio_led_off(void)
{
	*GPL2DAT &= 0xFE;
}

static int led_ioremap_init(void)
{
	printk(KERN_EMERG "++++++led_ioremap_init++++++\n");
	gpio_led_phy2vir();
	gpio_led_cfg();
	gpio_led_on();
	printk(KERN_EMERG "------led2 on------\n");
	return 0;
}

static void led_ioremap_exit(void)
{
	printk(KERN_EMERG "------led2 off------\n");
	gpio_led_off();
	iounmap((void *)vir_base_addr);
}

module_init(led_ioremap_init);
module_exit(led_ioremap_exit)
